package org.javaweb.http;

import org.apache.http.NameValuePair;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.CoreProtocolPNames;

import java.io.IOException;
import java.util.List;

/**
 * 测试Apache 下的HttpClient用法
 * Created by Administrator on 2016/12/15.
 */
public class HttpClientTest {

    /* URL of server */
    private String serverUrl;

    /* http method : get/post/put/delete */
    private String httpMethod;

    /* the date sent to server */
    private Object clientData;


    /* connection timeout */
    private int connectTimeout;

    /* the time to wait for data from server */
    private int socketTimeout;

    /**
     * Constructs client with URL, method, and data
     *
     * @param url    the url of server of REST
     * @param method method of HTTP(get/post/delete/put)
     * @param data   data in JSON format
     */
    public HttpClientTest(String url, String method, Object data) {
        this.serverUrl = url;
        this.httpMethod = method;
        this.clientData = data;
        this.connectTimeout = -1;
        this.socketTimeout = -1;
    }

    public String httpExecute() {
        String ret = null;
        DefaultHttpClient httpclient = getHttpClient();
        try {
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            if (httpMethod.equalsIgnoreCase("GET")) {
                /* set the data after URL */
                HttpGet req = new HttpGet(getURLWithData());
                ret = httpclient.execute(req, responseHandler);
            } else if (httpMethod.equalsIgnoreCase("POST")) {
                HttpPost req = new HttpPost(serverUrl);
                if (null != clientData) {
                    req.setEntity(new StringEntity(clientData.toString()));
                    req.setEntity(new UrlEncodedFormEntity((List<NameValuePair>)clientData));
                }
                ret = httpclient.execute(req, responseHandler);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            httpclient.getConnectionManager().shutdown();
        }
        return ret;
    }

    /**
     * append data in url
     *
     * @return url appended with data
     */
    private String getURLWithData() {
        if (clientData != null) {
            if (serverUrl.endsWith("?")) {
                return serverUrl + clientData;
            } else {
                return serverUrl + "?" + clientData;
            }
        }
        return serverUrl;
    }

    /**
     * get http client
     *
     * @return http client
     */
    private DefaultHttpClient getHttpClient() {
        DefaultHttpClient httpClient = new DefaultHttpClient();

		/* set parameters for request */
        httpClient.getParams().setParameter(
                CoreProtocolPNames.HTTP_CONTENT_CHARSET, "utf-8");
        if (0 < connectTimeout) {
            httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, connectTimeout * 1000);
        }
        if (0 < socketTimeout) {
            httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, socketTimeout * 1000);
        }
        return httpClient;
    }

    public String getServerUrl() {
        return serverUrl;
    }

    public void setServerUrl(String serverUrl) {
        this.serverUrl = serverUrl;
    }

    public String getHttpMethod() {
        return httpMethod;
    }

    public void setHttpMethod(String httpMethod) {
        this.httpMethod = httpMethod;
    }

    public Object getClientData() {
        return clientData;
    }

    public void setClientData(String clientData) {
        this.clientData = clientData;
    }

    public int getConnectTimeout() {
        return connectTimeout;
    }

    public void setConnectTimeout(int connectTimeout) {
        this.connectTimeout = connectTimeout;
    }

    public int getSocketTimeout() {
        return socketTimeout;
    }

    public void setSocketTimeout(int socketTimeout) {
        this.socketTimeout = socketTimeout;
    }
}
